home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libmpeg_src.lha / fs2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-25  |  9.1 KB  |  393 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. #include <config.h>
  22. #include "video.h"
  23. #include "dither.h"
  24. #include "fs2.h"
  25. #include "proto.h"
  26.  
  27. /* Structures for precomputed error propogation values. */
  28.  
  29. static FS2DithVal lum_index[256];
  30. static FS2DithVal cr_index[256];
  31. static FS2DithVal cb_index[256];
  32.  
  33.  
  34.  
  35. /*
  36.  *--------------------------------------------------------------
  37.  *
  38.  * InitFS2Dither --
  39.  *
  40.  *    Initializes structures for precomputed 2 error f-s dithering.
  41.  *      The value field of the structure contains the pixel component 
  42.  *      of the particular channel in question. Thus the addition of
  43.  *      the value field of a structure in the luminance index, a 
  44.  *      structure in the Cr index, and a structure in the Cb index will
  45.  *      yeild a color number. This color number can then be transformed
  46.  *      into a pixel value to be displayed. Each channel can then be
  47.  *      processed (i.e. dithered) separately, with the results being
  48.  *      added up and remapped to yield a final pixel value.
  49.  *
  50.  * Results:
  51.  *    None.
  52.  *
  53.  * Side effects:
  54.  *      None.
  55.  *
  56.  *--------------------------------------------------------------
  57.  */
  58.  
  59. void InitFS2Dither()
  60. {
  61.   int i;
  62.  
  63.   /* For each possible pixel value, precompute propogated error and
  64.      store in array.
  65.   */
  66.   
  67.   for (i=0; i<256; i++) {
  68.     lum_index[i].value = (i * LUM_RANGE) / 256;
  69.  
  70.     lum_index[i].e1 = (i-lum_values[lum_index[i].value]) / 2;
  71.     lum_index[i].e3 = (i - lum_values[lum_index[i].value]) - lum_index[i].e1;
  72.  
  73.     lum_index[i].value *= LUM_BASE;
  74.  
  75.     cr_index[i].value = (i * CR_RANGE) / 256; 
  76.  
  77.     cr_index[i].e1 = (i - cr_values[cr_index[i].value]) / 2;
  78.     cr_index[i].e3 = (i - cr_values[cr_index[i].value]) - cr_index[i].e1 ;
  79.  
  80.     cr_index[i].value *= CR_BASE;
  81.  
  82.     cb_index[i].value = (i * CB_RANGE) / 256; 
  83.  
  84.     cb_index[i].e1 = (i - cb_values[cb_index[i].value]) / 2;
  85.     cb_index[i].e3 = (i - cb_values[cb_index[i].value]) - cb_index[i].e1;
  86.  
  87.     cb_index[i].value *= CB_BASE;
  88.  
  89.   }
  90.  
  91. }
  92.  
  93.  
  94. /*
  95.  *--------------------------------------------------------------
  96.  *
  97.  * DitherImage --
  98.  *
  99.  *    Converts lum, cr, cb image planes into fixed colormap
  100.  *      space.
  101.  *
  102.  * Results:
  103.  *    the display plane is replaced by 8-bit colormap space
  104.  *      image.
  105.  *
  106.  * Side effects:
  107.  *      Hopefully, none.
  108.  *
  109.  *--------------------------------------------------------------
  110.  */
  111.  
  112. void FS2DitherImage(lum, cr, cb, disp, rows, cols)
  113.      unsigned char *lum, *cr, *cb, *disp;
  114.      int rows, cols;
  115. {
  116.   static char *cur_row_error, *next_row_error;
  117.   static int first = 1;
  118.   char  *cur_row_err_mark, *next_row_err_mark;
  119.   char *temp;
  120.   int i, j, pixsum, c_cols;
  121.   unsigned char *cur_row, *channel, *dest_row;
  122.   FS2DithVal *chan_index;
  123.  
  124.   /* Allocate error arrays. */
  125.  
  126.   if (first) {
  127.     cur_row_error = (char *) malloc(cols+2);
  128.     next_row_error = (char *) malloc(cols+2);
  129.     first = 0;
  130.   }
  131.  
  132.   /* Initialize error arrays. */
  133.  
  134.   memset(cur_row_error, 0, cols+2);
  135.   memset(next_row_error, 0, cols+2);
  136.  
  137.   /* Use luminance values first. */
  138.  
  139.   /* For each two rows, do... */
  140.  
  141.   for(i=0; i<rows; i+=2) {
  142.  
  143.     /* Establish pointer to current source and destination rows. */
  144.     cur_row = lum + (i*cols);
  145.     dest_row = disp + (i*cols);
  146.  
  147.     /* Establish pointers to error arrays. */
  148.     cur_row_err_mark = cur_row_error + 1;
  149.     next_row_err_mark = next_row_error + 1;
  150.  
  151.     
  152.     /* For each column within first row do... */
  153.  
  154.     for (j=0; j<cols; j++) {
  155.  
  156.       /* Calculate pixel value with error. */
  157.  
  158.       pixsum = *cur_row + *cur_row_err_mark;
  159.  
  160.       /* Bounds check. */
  161.       if (pixsum < 0) pixsum = 0;
  162.       else if (pixsum > 255) pixsum = 255;
  163.  
  164.       /* Establish dest value, propogate errors. */
  165.  
  166.       *dest_row = lum_index[pixsum].value;
  167.       *(cur_row_err_mark+1) += lum_index[pixsum].e1; 
  168.       *next_row_err_mark += lum_index[pixsum].e3; 
  169.  
  170.       /* Advance pointers. */
  171.  
  172.       cur_row++;
  173.       dest_row++;
  174.       cur_row_err_mark++;
  175.       next_row_err_mark++;
  176.     }
  177.  
  178.     /* Switch error arrays, so next row errors are now current row errors, and
  179.        vice versa. 
  180.     */
  181.  
  182.     temp = cur_row_error;
  183.     cur_row_error = next_row_error;
  184.     next_row_error = temp;
  185.  
  186.     /* Reset next row errors. */
  187.  
  188.     memset(next_row_error, 0, cols+2); 
  189.  
  190.     /* Establish pointers for second row. This one will be processed right to
  191.        left to establish serpantine motion.
  192.     */
  193.  
  194.     cur_row += cols-1;
  195.     dest_row += cols-1;
  196.     cur_row_err_mark = cur_row_error + cols;
  197.     next_row_err_mark = next_row_error + cols;
  198.  
  199.     /* Process each column... */
  200.  
  201.     for (j=0; j<cols; j++) {
  202.  
  203.       pixsum = *cur_row + *cur_row_err_mark;
  204.       if (pixsum < 0) pixsum = 0;
  205.       else if (pixsum > 255) pixsum = 255;
  206.       
  207.       *dest_row = lum_index[pixsum].value;
  208.       *(cur_row_err_mark-1) += lum_index[pixsum].e1; 
  209.       *next_row_err_mark += lum_index[pixsum].e3; 
  210.       
  211.       cur_row--;
  212.       dest_row--;
  213.       cur_row_err_mark--;
  214.       next_row_err_mark--;
  215.     }
  216.  
  217.     /* Switch error arrays. */
  218.  
  219.     temp = cur_row_error;
  220.     cur_row_error = next_row_error;
  221.     next_row_error = temp;
  222.  
  223.     /* Reset next row errors. */
  224.  
  225.     memset(next_row_error, 0, cols+2); 
  226.   }
  227.  
  228.   /* Reset error arrays. */
  229.  
  230.   memset(cur_row_error, 0, cols+2); 
  231.   
  232.   /* Establish column length divided by two. */
  233.  
  234.   c_cols = cols >> 1;
  235.  
  236.   /* Set channel to Cr. Use Cr index. */
  237.  
  238.   channel = cr;
  239.   chan_index = cr_index;
  240.   
  241.  repeat:
  242.  
  243.   /* Process each row of chrominance data... */
  244.  
  245.   for (i=0; i < rows; i+=2) {
  246.  
  247.     /* Establish pointers. */
  248.  
  249.     cur_row = channel + ((i>>1)*c_cols);
  250.     dest_row = disp + (i*cols);
  251.  
  252.     cur_row_err_mark = cur_row_error+1;
  253.     next_row_err_mark = next_row_error+1;
  254.  
  255.     /* For each column in row... */
  256.  
  257.     for (j=0; j<cols; j++) {
  258.       int p_val;
  259.  
  260.       /* Get pixel value as twos bit complement. */
  261.  
  262.       p_val = *cur_row;
  263.  
  264.       /* Add error term. */
  265.  
  266.       pixsum = *cur_row_err_mark + p_val;
  267.  
  268.       /* Bounds check. */
  269.  
  270.       if (pixsum < 0) pixsum = 0;
  271.       else if (pixsum > 255) pixsum = 255;
  272.  
  273.       /* Increment dest value. */
  274.  
  275.       *dest_row += chan_index[pixsum].value;
  276.  
  277.       /* Propogate error values. */
  278.  
  279.       *(cur_row_err_mark+1) += chan_index[pixsum].e1; 
  280.       *next_row_err_mark += chan_index[pixsum].e3; 
  281.  
  282.  
  283.       /* If count is odd, advance source pointer (Cr and Cb channels are 2:1 
  284.      subsampled.
  285.       */
  286.  
  287.       if (j&1) cur_row++;
  288.  
  289.       /* Advance destination and error pointers. */
  290.  
  291.       dest_row++;
  292.       cur_row_err_mark++;
  293.       next_row_err_mark++;
  294.     }
  295.  
  296.     /* Switch error arrays. */
  297.  
  298.     temp = cur_row_error;
  299.     cur_row_error = next_row_error;
  300.     next_row_error = temp;
  301.  
  302.     /* Reset next row errors. */
  303.  
  304.     memset(next_row_error, 0, cols+2);
  305.  
  306.     /* Re-establish pointers. */
  307.  
  308.     cur_row += c_cols-1;
  309.     dest_row += cols-1;
  310.     cur_row_err_mark = cur_row_error+cols;
  311.     next_row_err_mark = next_row_error+cols;
  312.  
  313.     /* Process second row right to left. */
  314.  
  315.     for (j=0; j<cols; j++) {
  316.       int p_val;
  317.  
  318.       /* Get source value as twos bit complement. */
  319.  
  320.       p_val = *cur_row;
  321.  
  322.       /* Add error. */
  323.  
  324.       pixsum = *cur_row_err_mark + p_val;
  325.  
  326.       /* Bounds check. */
  327.  
  328.       if (pixsum < 0) pixsum = 0;
  329.       else if (pixsum > 255) pixsum = 255;
  330.  
  331.       /* Increment dest value. */
  332.  
  333.       *dest_row += chan_index[pixsum].value;
  334.  
  335.       /* Propogate errors. */
  336.  
  337.       *(cur_row_err_mark-1) += chan_index[pixsum].e1; 
  338.       *next_row_err_mark += chan_index[pixsum].e3; 
  339.  
  340.       /* If column counters is odd, decrement source pointer. */
  341.  
  342.       if (j&1) cur_row--;
  343.  
  344.       /* Decrement dest and error pointers. */
  345.  
  346.       dest_row--;
  347.       cur_row_err_mark--;
  348.       next_row_err_mark--;
  349.     }
  350.  
  351.     /* Switch error arrays. */
  352.  
  353.     temp = cur_row_error;
  354.     cur_row_error = next_row_error;
  355.     next_row_error = temp;
  356.  
  357.     /* Reinitialize next row errors. */
  358.  
  359.     memset(next_row_error, 0, cols+2);
  360.   }
  361.  
  362.   /* If Cr channel completed, set channel to Cb and Cb index and repeat. */
  363.  
  364.   if (channel == cr) {
  365.     channel = cb;
  366.     chan_index = cb_index;
  367.     memset(cur_row_error, 0, cols+2);
  368.  
  369.     goto repeat;
  370.   }
  371.  
  372.   /* Establish pointer to start of display frame. */
  373.  
  374.   dest_row = disp;
  375.  
  376.   /* Transform all display values to pixel values. */
  377.  
  378.   for (i=0; i<rows; i++) {
  379.     for (j=0; j<cols; j++) {
  380.       *dest_row =  pixel[*dest_row];
  381.       dest_row++;
  382.     }
  383.   }
  384. }
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.